package com.fifth.back.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fifth.back.entity.Anon;
import com.fifth.back.entity.Path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/*
 * @作者：刘壬杉
 * @创建时间 2022/8/30 20:15
 */

@Component
public class LoginFilter implements GlobalFilter, Ordered {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private Anon anon;

    @Autowired
    private Path paths;


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        List<String> list = paths.getRoutes().stream().map(item->"/"+item.getId().substring(6)).collect(Collectors.toList());

        ServerHttpResponse response = exchange.getResponse();
        ServerHttpRequest request = exchange.getRequest();
        //解决中文乱码
        response.getHeaders().add("Content-Type","application/json;charset=UTF-8");

        String path = request.getPath().toString();
        if (anon.getUrl().contains(path)){
            return chain.filter(exchange);
        }
        String token = request.getHeaders().getFirst("token");
        if (StringUtils.hasText(token) && redisTemplate.hasKey(token)){
            if (anon.getLogin().contains(path)){
                return chain.filter(exchange);
            }
            ValueOperations<String, String> forValue = redisTemplate.opsForValue();
            Map map = JSON.parseObject(forValue.get(token), Map.class);
            List<String> permission = (List<String>) map.get("permissions");
            //截取请求路径中第二个/之前的内容
            String s1 = path.substring(0, path.indexOf("/", path.indexOf("/") + 1));
            boolean permissions = map.containsKey("permissions");
            if (permissions==true) {
                 permission = (List<String>) map.get("permissions");
            }
            if (permission.contains(path)){
                return chain.filter(exchange);
            }else if(list.contains(s1)) {
                return chain.filter(exchange);
            }else {
                return result(response,"权限不足",4001);
            }
        }
        return result(response,"未登录",4002);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    private Mono<Void> result(ServerHttpResponse response ,String msg,Integer code){
        //3.返回一个json数据。
        //3.1设置状态码
        response.setStatusCode(HttpStatus.UNAUTHORIZED);

        //3.2封装返回数据
        Map<String, Object> map = new HashMap<>();
        map.put("msg", msg);
        map.put("code", code);

        //3.3作JSON转换
        byte[] bytes = JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8);

        //3.4调用bufferFactory方法,生成DataBuffer对象
        DataBuffer buffer = response.bufferFactory().wrap(bytes);

        //4.调用Mono中的just方法,返回要写给前端的JSON数据
        return response.writeWith(Mono.just(buffer));
    }
}
